using System;
using System.Collections.Generic;
using TTDotNet.Engine.ThreeDEngine;
using TTDotNet.Engine.Vehicles;
using TTDotNet.Engine.Terrain;
using TTDotNet.Engine.Networks;
using TTDotNet.Engine.Companies;
using TTDotNet.Util;
using System.Diagnostics;

namespace TTDotNet.Engine
{
    public class World
    {
        private const float timeFactor = 86400 * 0.5f;
        //private bool gamePaused;
        private AJScene scene;
        private Map worldMap;
        public static DDDRoadNetwork roadNetwork;

        private GameTimer frameTimer;
        private GameTimer gameTimer;

        private int frames;
        private int lastFrames;

        private DateTime worldDate;
        
        private Dictionary<int, Company> gameCompanies;
        private List<Town> gameTowns;

        private TimeSpan perSecond;

        public World(int width, int length)
        {
            this.scene = new AJScene();
            this.worldMap = new Map(width, length);
            gameCompanies = new Dictionary<int, Company>();
            gameTowns = new List<Town>();
            roadNetwork = new DDDRoadNetwork();

            frameTimer = new GameTimer();
            frameTimer.Start();

            gameTimer = new GameTimer();
            gameTimer.Start();
            
            worldDate = new DateTime(1950, 1, 1);

            SetupWorldMap();
        }

        public void AddVehicle(int playerNumber, Vehicle vehicle)
        {
            gameCompanies[playerNumber].AddVehicle(vehicle);
        }

        public void CreateNewTown(string name, Coordinate coord)
        {
            gameTowns.Add(new Town(name, coord));
        }

        public int CreateNewCompany()
        {
            int companyNum = 0;

            while (gameCompanies.ContainsKey(companyNum))
            {
                companyNum++;
            }

            gameCompanies[companyNum] = new Company(new DateTime(worldDate.Year));
            return companyNum;
        }

        private void SetupWorldMap()
        {
            #region Coordinate/CornerSet Setup

            //Stopwatch sw = new Stopwatch();
            //sw.Start();

            ////GameTexture grass = Game.texLoader.GetTexture(TileType.Grass);

            ////for (int y = 0; y < worldMap.Length; y++)
            ////{
            ////    for (int x = 0; x < worldMap.Width; x++)
            ////    {
            ////        //DDDCoordinate coord = new DDDCoordinate(x, 0, y);
            ////        //worldMap.SetTile(new Tile(coord, grass, LandType.Grass));
            ////    }
            ////}

            //sw.Stop();

            worldMap.setupGrid();
            scene.AddObject(worldMap.Grid);

            

            #endregion
        }

        public void Update()
        {
            float elapsedRealTime = gameTimer.ElapsedFraction;
            gameTimer.Reset();
            gameTimer.Start();

            if (elapsedRealTime > 0.1f) elapsedRealTime = 0.1f;

            if (!Paused)
            {

                TimeSpan passed = new TimeSpan(0, 0, (int)(elapsedRealTime * timeFactor));

                foreach (Company c in gameCompanies.Values)
                {
                    c.Update(elapsedRealTime, passed);
                }              

                foreach (Town t in gameTowns)
                {
                    t.Update(passed);
                }

                worldMap.UpdateLand();

                perSecond = perSecond.Add(passed);

                worldDate = worldDate.AddSeconds(elapsedRealTime * timeFactor);
            }

            frames++;
            

            if (frameTimer.ElapsedFraction > 1)
            {
                frameTimer.Reset();
                frameTimer.Start();
                lastFrames = frames;
                frames = 0;
                perSecond = new TimeSpan();
            }
        }

        public Company GetCompany(int num)
        {
            return gameCompanies[num];
        }

        public Map Map
        {
            get { return worldMap; }
        }

        public bool Paused
        {
            get { return Game.paused; }
            set
            {
                if(value) 
                { 
                    frameTimer.Stop();  
                }
                else
                {
                    frameTimer.Start(); 
                }
                //gamePaused = value;
            }
        }

        public Dictionary<int, Company> Companies
        {
            get { return gameCompanies; }
        }

        public AJScene Scene
        {
            get { return scene; }
        }

        public DDDRoadNetwork RoadNetwork
        {
            get { return roadNetwork; }
        }

        public DateTime CurrentDate
        {
            get { return worldDate; }
        }

        public List<Town> Towns
        {
            get { return gameTowns; }
        }

        public int Width
        {
            get { return worldMap.Width; }
        }

        public int Length
        {
            get { return worldMap.Length; }
        }

        public float FPS
        {
            get { return lastFrames  ; }
        }



    }
}
